

/**所有权
 *  所有权概念本身的含义并不复杂，但作为Rust语言的核心功能，它对语言的其他部分产生了十分深远的影响。
 *
 * 所有权规则:
 * •  Rust中的每一个值都有一个对应的变量作为它的所有者。
 * • 在同一时间内，值有且仅有一个所有者。
 * • 当所有者离开自己的作用域时，它持有的值就会被释放掉。
 */
fn main() {
    println!("Hello, world!");

    let mut _an = 19;

    let s = "  world";
    //这里的双冒号（::）运算符允许我们调用置于String命名空间下面的特定from函数，而不需要使用类似于string_from这样的名字
    let mut s_hello = String::from("hello");
    s_hello.push_str(s);
    println!("{}", s_hello);
//         在C++中，这种在对象生命周期结束时释放资源的模式有时也被称作资源获取即初始化（Resource Acquisition Is Initialization）
// 。假如你使用过类似的模式，那么你应该对Rust中的特殊函数drop并不陌生
    //变量和数据的交互方式: 移动
    let _x = 5;
    let _y = _x;

//         字符串的数据移动
    let _s1 = "hello";
    let _s2 = _s1;
    println!("{}", _s2);

//         如果使用String::from("") 给s3赋值   再把s3赋值给s4 这样打印s3编译会报错
    let _s3 = String::from("hello");
    // let _s4=_s3;
    // println!("{},world",_s3);
//         解决上面的问题可以使用 clone()方法  显示的生成数据   复制了堆上_s3的数据赋值给了_s5
    let _s5 = _s3.clone();
    println!("{}+++{}", _s3, _s5);

//         栈上数据的复制
    let _x = 5;
    let _y = _x;
    println!("_x={},_y={}", _x, _y);

    //借用和引用
    let _s6=String::from("clone");
    let lent=calculate_length(&_s6);
    println!("The length  of {} is {}",_s6,lent);
    let mut _s7=String::from("clone");
    change(& mut _s7);

    let dangle_str =dangle();
    println!("{}", dangle_str);
}
//  此方法编译不过   
fn calculate_length(s:&String)->usize{
    s.len()
}
//此方法编译不过   因为 引用是默认不可变的，Rust不允许我们去修改引用指向的值。
fn change(some_string:& mut String){
    // some_string.push_str(", this");
    some_string.push_str(",this");

}

//悬垂引用
fn dangle()->String{
    let  s=String::from("hello, 所有权");
    //&s    //这行代码会报错   this function's return type contains a borrowed value, but there is no value for it to be borrowed from
    s      //去掉 &符号   直接返回就可以运行
}

// 总结:
//     z在任何一段给定的时间里,你要么智能拥有一个可变引用,要么智能拥有任意数量的不可变引用
//      应用总是有效的




